// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using System.Threading;
using Microsoft.Tools.CodeRunner;

namespace Microsoft.Tools.CodeRunner.UnitTest
{

	[TestClass]
	
	public class ProcessInjectorTests 
	{
		[TestMethod]
		[DeploymentItem(@"UnitTest\Antidote\Debug\Antidote.dll")]
		[DeploymentItem(@"UnitTest\Injectee\Debug\Injectee.exe")]
		public void TestProcessInjector() 
		{
			// Create some events to signal injection, and stop the injected thread and remote process
			EventWaitHandle signalEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "SignalInjection");
			EventWaitHandle finishEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "FinishInjection");
			EventWaitHandle stopInjecteeEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "StopInjectee");
			
			// Create the injectee process
			Process p = Process.Start("injectee.exe");
			
			Assert.IsNotNull(p);
			
			ProcessInjector injector = new ProcessInjector(p.Id, "antidote.dll", "AdministerAntidote");
			
			Assert.IsTrue(signalEvent.WaitOne(10000, false));
			
			// Stop the injected thread
			finishEvent.Set();
			
			// Wait for injected thread to stop and get its exit code
			injector.WaitForExit();
			
			Assert.IsTrue(injector.ExitCode == 0);
			
			stopInjecteeEvent.Set();
			
			// Wait for the process to stop
			p.WaitForExit();
			p.Close();
		}
	}
}
